<!Doctype html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>C++ 多线程 | 菜鸟教程</title>

  <meta name='robots' content='max-image-preview:large' />
<link rel='stylesheet' id='classic-theme-styles-css' href='../0/classic-themes.min.css?ver=6.2' type='text/css' media='all' />
<link rel="canonical" href="../w3cnote/cpp-multithread-demo.html" />
<meta name="keywords" content="C++ 多线程">
<meta name="description" content="创建线程  在Windows平台，Windows API提供了对多线程的支持。前面进程和线程的概念中我们提到，一个程序至少有一个线程，这个线程称为主线程(main thread)，如果我们不显示地创建线程，那我们产的程序就是只有主线程的间线程程序。  下面，我们看看Windows中线程相关的操作和方法：  CreateThread 与 CloseHandle  CreateThread 用于创建一个线程，其函数原型如下：   HANDL..">
		
	<link rel="shortcut icon" href="https://static.runoob.com/images/favicon.ico">
	<link rel="stylesheet" href="../0/style.css?v=1.170" type="text/css" media="all" />	
	<link rel="stylesheet" href="../0/font-awesome.min.css" media="all" />	
  <!--[if gte IE 9]><!-->
  <script src=""></script>
  <!--<![endif]-->
  <!--[if lt IE 9]>
     <script src=""></script>
     <script src=""></script>
  <![endif]-->
  <link rel="apple-touch-icon" href="https://static.runoob.com/images/icon/mobile-icon.png"/>
  <meta name="apple-mobile-web-app-title" content="菜鸟教程">
</head>
<body>

<!--  头部 -->
<div class="container logo-search">

  <div class="col search row-search-mobile">
    <form action="index.php">
      <input class="placeholder" placeholder="搜索……" name="s" autocomplete="off">
      
    </form>
  </div>

  <div class="row">
    <div class="col logo">
      <h1><a href="../">菜鸟教程 -- 学的不仅是技术，更是梦想！</a></h1>
    </div>
        <div class="col right-list"> 
    <button class="btn btn-responsive-nav btn-inverse" data-toggle="collapse" data-target=".nav-main-collapse" id="pull" style=""> <i class="fa fa-navicon"></i> </button>
    </div>
        
    <div class="col search search-desktop last">
      <div class="search-input" >
      <form action="//www.runoob.com/" target="_blank">
        <input class="placeholder" id="s" name="s" placeholder="搜索……"  autocomplete="off" style="height: 44px;">
      </form>
      
      </div>
    </div>
  </div>
</div>



<!-- 导航栏 -->
<div class="container navigation">
    <div class="row">
        <div class="col nav">
            

                        <ul class="pc-nav" id="note-nav">
                <li><a href="../">首页</a></li>
                <li><a href="../w3cnote">笔记首页</a></li>
                <li><a href="../w3cnote/android-tutorial-intro.html" title="Android 基础入门教程">Android</a></li>
                <li><a href="../w3cnote/es6-tutorial.html" title="ES6 教程">ES6 教程</a></li>
                <li><a href="../w3cnote/ten-sorting-algorithm.html" title="排序算法">排序算法</a></li>
                <li><a href="../w3cnote/hadoop-tutorial.html" title="Hadoop 教程">Hadoop</a></li>
                <li><a href="../w3cnote/zookeeper-tutorial.html" title="Zookeeper 教程">Zookeeper</a></li>
                <li><a href="../w3cnote/verilog-tutorial.html" title="Verilog 教程">Verilog</a></li>
                <li><a href="../w3cnote_genre/code" title="编程技术">编程技术</a></li> 
                <li><a href="../w3cnote_genre/coderlife" title="程序员人生">程序员人生</a></li>
                
                <!--<li><a href="javascript:;" class="runoob-pop">登录</a></li>
                
                
                        <li>
                <a style="font-weight:bold;" href="../linux/linux-tutorial.html#yunserver" target="_blank" onclick="_hmt.push(['_trackEvent', 'aliyun', 'click', 'aliyun'])" title="kkb">云服务器</a>
                </li>
                <li><a href="http://gk.link/a/104mQ" target="_blank" style="font-weight: bold;"onclick="_hmt.push(['_trackEvent', '极客时间', 'click', 'jike'])" title="我的圈子">极客时间</a></li>
            
                
                <li><a target="_blank" href="../shoppinglist" rel="nofollow">知识店铺</a></li> 
        -->
            </ul>
                        
              
            <ul class="mobile-nav">
                <li><a href="../w3cnote">首页</a></li>
                <li><a href="../w3cnote_genre/android" target="_blank" title="Android 基础入门教程">Android</a></li>
                <li><a href="../w3cnote/es6-tutorial.html" target="_blank" title="ES6 教程">ES6</a></li>
                <li><a href="../w3cnote_genre/joke" target="_blank" title="程序员笑话">逗乐</a></li>
                
                <a href="javascript:void(0)" class="search-reveal">Search</a> 
            </ul>
            
        </div>
    </div>
</div>


<!--  内容  -->
<div class="container main">
	<div class="row">

		<div class="col middle-column big-middle-column">
	 			<div class="article">
			<div class="article-heading">
				<h2>C++ 多线程</h2>				<h3><em>分类</em> <a href="../w3cnote_genre/code" title="编程技术" >编程技术</a> </h3>
			</div>
			<div class="article-body note-body">
				<div class="article-intro">
					
<h2>创建线程</h2>

<p>在Windows平台，Windows API提供了对多线程的支持。前面进程和线程的概念中我们提到，一个程序至少有一个线程，这个线程称为主线程(main thread)，如果我们不显示地创建线程，那我们产的程序就是只有主线程的间线程程序。 </p>
<p>下面，我们看看Windows中线程相关的操作和方法：</p>

<h3>CreateThread 与 CloseHandle</h3>

<p>CreateThread 用于创建一个线程，其函数原型如下：</p>

<pre>
HANDLE WINAPI CreateThread(
    LPSECURITY_ATTRIBUTES   lpThreadAttributes, //线程安全相关的属性，常置为NULL
    SIZE_T                  dwStackSize,        //新线程的初始化栈在大小，可设置为0
    LPTHREAD_START_ROUTINE  lpStartAddress,     //被线程执行的回调函数，也称为线程函数
    LPVOID                  lpParameter,        //传入线程函数的参数，不需传递参数时为NULL
    DWORD                   dwCreationFlags,    //控制线程创建的标志
    LPDWORD                 lpThreadId          //传出参数，用于获得线程ID，如果为NULL则不返回线程ID
);
</pre>


<p>说明：</p>
<ul><li><p>
lpThreadAttributes：指向SECURITY_ATTRIBUTES结构的指针，决定返回的句柄是否可被子进程继承，如果为NULL则表示返回的句柄不能被子进程继承。
</p></li><li>
dwStackSize ：线程栈的初始化大小，字节单位。系统分配这个值对
</li><li><p>
lpStartAddress：指向一个函数指针，该函数将被线程调用执行。因此该函数也被称为线程函数(ThreadProc)，是线程执行的起始地址，线程函数是一个回调函数，由操作系统在线程中调用。线程函数的原型如下：</p>
<pre>
DWORD WINAPI ThreadProc(LPVOID lpParameter);    //lpParameter是传入的参数，是一个空指针</pre>
</li><li><p>
lpParameter：传入线程函数(ThreadProc)的参数，不需传递参数时为NULL
</p></li><li><p>
dwCreationFlags：控制线程创建的标志，有三个类型，0：线程创建后立即执行线程；CREATE_SUSPENDED：线程创建后进入就绪状态，直到线程被唤醒时才调用；STACK_SIZE_PARAM_IS_A_RESERVATION：dwStackSize 参数指定线程初始化栈的大小，如果STACK_SIZE_PARAM_IS_A_RESERVATION标志未指定，dwStackSize将会设为系统预留的值。
</p></li><li><p>
返回值：如果线程创建成功，则返回这个新线程的句柄，否则返回NULL。如果线程创建失败，可通过GetLastError函数获得错误信息。
</p><pre>
BOOL WINAPI CloseHandle(HANDLE hObject);        //关闭一个被打开的对象句柄
</pre>
可用这个函数关闭创建的线程句柄，如果函数执行成功则返回true(非0),如果失败则返回false(0)，如果执行失败可调用GetLastError.函数获得错误信息。</p></li></ul>
<h3>【Demo1】：创建一个最简单的线程</h3>
<div class="example">
<h2 class="example">实例</h2>
<div class="example_code">
<div class="hl-main"><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">stdafx.h</span><span class="hl-quotes">&quot;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">windows.h</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">iostream</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-reserved">using</span><span class="hl-code"> </span><span class="hl-types">namespace</span><span class="hl-code"> </span><span class="hl-identifier">std</span><span class="hl-code">;
 
</span><span class="hl-comment">//线程函数</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-identifier">DWORD</span><span class="hl-code"> </span><span class="hl-identifier">WINAPI</span><span class="hl-code"> </span><span class="hl-identifier">ThreadProc</span><span class="hl-brackets">(</span><span class="hl-identifier">LPVOID</span><span class="hl-code"> </span><span class="hl-identifier">lpParameter</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">i</span><span class="hl-code"> = </span><span class="hl-number">0</span><span class="hl-code">; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt; </span><span class="hl-number">5</span><span class="hl-code">; ++ </span><span class="hl-identifier">i</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">子线程:i = </span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
        </span><span class="hl-identifier">Sleep</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-identifier">L</span><span class="hl-code">;
</span><span class="hl-brackets">}</span><span class="hl-code">
 
</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">main</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-comment">//创建一个线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">HANDLE</span><span class="hl-code"> </span><span class="hl-identifier">thread</span><span class="hl-code"> = </span><span class="hl-identifier">CreateThread</span><span class="hl-brackets">(</span><span class="hl-prepro">NULL</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">ThreadProc</span><span class="hl-code">, </span><span class="hl-prepro">NULL</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-prepro">NULL</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-comment">//关闭线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">CloseHandle</span><span class="hl-brackets">(</span><span class="hl-identifier">thread</span><span class="hl-brackets">)</span><span class="hl-code">;
 
    </span><span class="hl-comment">//主线程的执行路径</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">i</span><span class="hl-code"> = </span><span class="hl-number">0</span><span class="hl-code">; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt; </span><span class="hl-number">5</span><span class="hl-code">; ++ </span><span class="hl-identifier">i</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">主线程:i = </span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
        </span><span class="hl-identifier">Sleep</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
 
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-code">;
</span><span class="hl-brackets">}</span></div>
</div>
</div>
<p>
结果如下：</p>

<pre>主线程:i = 0 
子线程:i = 0 
主线程:i = 1 
子线程:i = 1 
子线程:i = 2 
主线程:i = 2 
子线程:i = 3 
主线程:i = 3 
子线程:i = 4 
主线程:i = 4</pre>

<h3>【Demo2】：在线程函数中传入参数</h3>
<div class="example">
<h2 class="example">实例</h2>
<div class="example_code">
<div class="hl-main"><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">stdafx.h</span><span class="hl-quotes">&quot;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">windows.h</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">iostream</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-reserved">using</span><span class="hl-code"> </span><span class="hl-types">namespace</span><span class="hl-code"> </span><span class="hl-identifier">std</span><span class="hl-code">;
 
</span><span class="hl-prepro">#define</span><span class="hl-code"> </span><span class="hl-identifier">NAME_LINE</span><span class="hl-code">   </span><span class="hl-number">40</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-comment">//定义线程函数传入参数的结构体</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-types">typedef</span><span class="hl-code"> </span><span class="hl-types">struct</span><span class="hl-code"> </span><span class="hl-identifier">__THREAD_DATA</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">nMaxNum</span><span class="hl-code">;
    </span><span class="hl-types">char</span><span class="hl-code"> </span><span class="hl-identifier">strThreadName</span><span class="hl-brackets">[</span><span class="hl-identifier">NAME_LINE</span><span class="hl-brackets">]</span><span class="hl-code">;
 
    </span><span class="hl-identifier">__THREAD_DATA</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code"> : </span><span class="hl-identifier">nMaxNum</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">memset</span><span class="hl-brackets">(</span><span class="hl-identifier">strThreadName</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">NAME_LINE</span><span class="hl-code"> * </span><span class="hl-reserved">sizeof</span><span class="hl-brackets">(</span><span class="hl-types">char</span><span class="hl-brackets">)</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
</span><span class="hl-brackets">}</span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code">;
 
 
 
</span><span class="hl-comment">//线程函数</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-identifier">DWORD</span><span class="hl-code"> </span><span class="hl-identifier">WINAPI</span><span class="hl-code"> </span><span class="hl-identifier">ThreadProc</span><span class="hl-brackets">(</span><span class="hl-identifier">LPVOID</span><span class="hl-code"> </span><span class="hl-identifier">lpParameter</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code">* </span><span class="hl-identifier">pThreadData</span><span class="hl-code"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code">*</span><span class="hl-brackets">)</span><span class="hl-identifier">lpParameter</span><span class="hl-code">;
 
    </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">i</span><span class="hl-code"> = </span><span class="hl-number">0</span><span class="hl-code">; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt; </span><span class="hl-identifier">pThreadData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">nMaxNum</span><span class="hl-code">; ++ </span><span class="hl-identifier">i</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">pThreadData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">strThreadName</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string"> --- </span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
        </span><span class="hl-identifier">Sleep</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-identifier">L</span><span class="hl-code">;
</span><span class="hl-brackets">}</span><span class="hl-code">
 
</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">main</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-comment">//初始化线程数据</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code"> </span><span class="hl-identifier">threadData1</span><span class="hl-code">, </span><span class="hl-identifier">threadData2</span><span class="hl-code">;
    </span><span class="hl-identifier">threadData1</span><span class="hl-code">.</span><span class="hl-identifier">nMaxNum</span><span class="hl-code"> = </span><span class="hl-number">5</span><span class="hl-code">;
    </span><span class="hl-identifier">strcpy</span><span class="hl-brackets">(</span><span class="hl-identifier">threadData1</span><span class="hl-code">.</span><span class="hl-identifier">strThreadName</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">线程1</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-identifier">threadData2</span><span class="hl-code">.</span><span class="hl-identifier">nMaxNum</span><span class="hl-code"> = </span><span class="hl-number">10</span><span class="hl-code">;
    </span><span class="hl-identifier">strcpy</span><span class="hl-brackets">(</span><span class="hl-identifier">threadData2</span><span class="hl-code">.</span><span class="hl-identifier">strThreadName</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">线程2</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//创建第一个子线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">HANDLE</span><span class="hl-code"> </span><span class="hl-identifier">hThread1</span><span class="hl-code"> = </span><span class="hl-identifier">CreateThread</span><span class="hl-brackets">(</span><span class="hl-prepro">NULL</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">ThreadProc</span><span class="hl-code">, &amp;</span><span class="hl-identifier">threadData1</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-prepro">NULL</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-comment">//创建第二个子线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">HANDLE</span><span class="hl-code"> </span><span class="hl-identifier">hThread2</span><span class="hl-code"> = </span><span class="hl-identifier">CreateThread</span><span class="hl-brackets">(</span><span class="hl-prepro">NULL</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">ThreadProc</span><span class="hl-code">, &amp;</span><span class="hl-identifier">threadData2</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-prepro">NULL</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-comment">//关闭线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">CloseHandle</span><span class="hl-brackets">(</span><span class="hl-identifier">hThread1</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-identifier">CloseHandle</span><span class="hl-brackets">(</span><span class="hl-identifier">hThread2</span><span class="hl-brackets">)</span><span class="hl-code">;
 
    </span><span class="hl-comment">//主线程的执行路径</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">i</span><span class="hl-code"> = </span><span class="hl-number">0</span><span class="hl-code">; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt; </span><span class="hl-number">5</span><span class="hl-code">; ++ </span><span class="hl-identifier">i</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">主线程 === </span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
        </span><span class="hl-identifier">Sleep</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
 
    </span><span class="hl-identifier">system</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">pause</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-code">;
</span><span class="hl-brackets">}</span></div>
</div>
</div>
<p>结果：</p>
<pre>主线程 === 线程1 &mdash; 0 
0 
线程2 &mdash; 0 
线程1 &mdash; 1 
主线程 === 1 
线程2 &mdash; 1 
主线程 === 2 
线程1 &mdash; 2 
线程2 &mdash; 2 
主线程 === 3 
线程2 &mdash; 3 
线程1 &mdash; 3 
主线程 === 4 
线程2 &mdash; 4 
线程1 &mdash; 4 
线程2 &mdash; 5 
请按任意键继续&hellip; 线程2 &mdash; 6 
线程2 &mdash; 7 
线程2 &mdash; 8 
线程2 &mdash; 9</pre>

<h2>
CreateMutex、WaitForSingleObject、ReleaseMutex
</h2>
<p>从【Demo2】中可以看出，虽然创建的子线程都正常执行起来了，但输出的结果并不是我们预期的效果。我们预期的效果是每输出一条语句后自动换行，但结果却并非都是这样。这是因为在线程执行时没有做同步处理，比如第一行的输出，主线程输出"主线程 ==="后时间片已用完，这时轮到子线程1输出，在子线程输出"线程1 —"后时间片也用完了，这时又轮到主线程执行输出"0"，之后又轮到子线程1输出"0"。于是就出现了"主线程 === 线程1 — 0 0"的结果。</p>


<p>主线程：cout &lt;&lt; "主线程 === " &lt;&lt; i &lt;&lt; endl; <br>
子线程：cout &lt;&lt; pThreadData-&gt;strThreadName &lt;&lt; " — " &lt;&lt; i &lt;&lt; endl;</p>
<p>为避免出现这种情况，我们对线程做一些简单的同步处理，这里我们用互斥量(Mutex)。</p>

<p>互斥量(Mutex)和二元信号量类似，资源仅允许一个线程访问。与二元信号量不同的是，信号量在整个系统中可以被任意线程获取和释放，也就是说，同一个信号量可以由一个线程获取而由另一线程释放。而互斥量则要求哪个线程获取了该互斥量锁就由哪个线程释放，其它线程越俎代庖释放互斥量是无效的。</p>

<p>在使用互斥量进行线程同步时会用到以下几个函数：</p>

<pre>
HANDLE WINAPI CreateMutex(
    LPSECURITY_ATTRIBUTES lpMutexAttributes,        //线程安全相关的属性，常置为NULL
    BOOL                  bInitialOwner,            //创建Mutex时的当前线程是否拥有Mutex的所有权
    LPCTSTR               lpName                    //Mutex的名称
);
</pre>


<p><strong>说明：</strong> lpMutexAttributes也是表示安全的结构，与CreateThread中的lpThreadAttributes功能相同，表示决定返回的句柄是否可被子进程继承，如果为NULL则表示返回的句柄不能被子进程继承。bInitialOwner表示创建Mutex时的当前线程是否拥有Mutex的所有权，若为TRUE则指定为当前的创建线程为Mutex对象的所有者，其它线程访问需要先ReleaseMutex。lpName为Mutex的名称。</p>
<pre>
DWORD WINAPI WaitForSingleObject(
    HANDLE hHandle,                             //要获取的锁的句柄
    DWORD  dwMilliseconds                           //超时间隔
);
</pre>


<p><strong>说明：</strong> WaitForSingleObject的作用是等待一个指定的对象(如Mutex对象)，直到该对象处于非占用的状态(如Mutex对象被释放)或超出设定的时间间隔。除此之外，还有一个与它类似的函数WaitForMultipleObjects，它的作用是等待一个或所有指定的对象，直到所有的对象处于非占用的状态，或超出设定的时间间隔。 </p>
<p><strong>hHandle</strong>：要等待的指定对象的句柄。dwMilliseconds：超时的间隔，以毫秒为单位；如果dwMilliseconds为非0，则等待直到dwMilliseconds时间间隔用完或对象变为非占用的状态，如果dwMilliseconds 为INFINITE则表示无限等待，直到等待的对象处于非占用的状态。</p>

<pre>BOOL WINAPI ReleaseMutex(HANDLE hMutex);</pre>


<p><strong>说明：</strong>释放所拥有的互斥量锁对象，hMutex为释放的互斥量的句柄。</p>

<h3>【Demo3】：线程同步</h3>


<div class="example">
<h2 class="example">实例</h2>
<div class="example_code">
<div class="hl-main"><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">stdafx.h</span><span class="hl-quotes">&quot;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">windows.h</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">iostream</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-prepro">#define</span><span class="hl-code"> </span><span class="hl-identifier">NAME_LINE</span><span class="hl-code">   </span><span class="hl-number">40</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-comment">//定义线程函数传入参数的结构体</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-types">typedef</span><span class="hl-code"> </span><span class="hl-types">struct</span><span class="hl-code"> </span><span class="hl-identifier">__THREAD_DATA</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">nMaxNum</span><span class="hl-code">;
    </span><span class="hl-types">char</span><span class="hl-code"> </span><span class="hl-identifier">strThreadName</span><span class="hl-brackets">[</span><span class="hl-identifier">NAME_LINE</span><span class="hl-brackets">]</span><span class="hl-code">;
 
    </span><span class="hl-identifier">__THREAD_DATA</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code"> : </span><span class="hl-identifier">nMaxNum</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">memset</span><span class="hl-brackets">(</span><span class="hl-identifier">strThreadName</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">NAME_LINE</span><span class="hl-code"> * </span><span class="hl-reserved">sizeof</span><span class="hl-brackets">(</span><span class="hl-types">char</span><span class="hl-brackets">)</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
</span><span class="hl-brackets">}</span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code">;
 
</span><span class="hl-identifier">HANDLE</span><span class="hl-code"> </span><span class="hl-identifier">g_hMutex</span><span class="hl-code"> = </span><span class="hl-prepro">NULL</span><span class="hl-code">;     </span><span class="hl-comment">//互斥量</span><span class="hl-comment"></span><span class="hl-code">
 
</span><span class="hl-comment">//线程函数</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-identifier">DWORD</span><span class="hl-code"> </span><span class="hl-identifier">WINAPI</span><span class="hl-code"> </span><span class="hl-identifier">ThreadProc</span><span class="hl-brackets">(</span><span class="hl-identifier">LPVOID</span><span class="hl-code"> </span><span class="hl-identifier">lpParameter</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code">* </span><span class="hl-identifier">pThreadData</span><span class="hl-code"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code">*</span><span class="hl-brackets">)</span><span class="hl-identifier">lpParameter</span><span class="hl-code">;
 
    </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">i</span><span class="hl-code"> = </span><span class="hl-number">0</span><span class="hl-code">; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt; </span><span class="hl-identifier">pThreadData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">nMaxNum</span><span class="hl-code">; ++ </span><span class="hl-identifier">i</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-comment">//请求获得一个互斥量锁</span><span class="hl-comment"></span><span class="hl-code">
        </span><span class="hl-identifier">WaitForSingleObject</span><span class="hl-brackets">(</span><span class="hl-identifier">g_hMutex</span><span class="hl-code">, </span><span class="hl-identifier">INFINITE</span><span class="hl-brackets">)</span><span class="hl-code">;
        </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">pThreadData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">strThreadName</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string"> --- </span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
        </span><span class="hl-identifier">Sleep</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
        </span><span class="hl-comment">//释放互斥量锁</span><span class="hl-comment"></span><span class="hl-code">
        </span><span class="hl-identifier">ReleaseMutex</span><span class="hl-brackets">(</span><span class="hl-identifier">g_hMutex</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-identifier">L</span><span class="hl-code">;
</span><span class="hl-brackets">}</span><span class="hl-code">
 
</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">main</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-comment">//创建一个互斥量</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">g_hMutex</span><span class="hl-code"> = </span><span class="hl-identifier">CreateMutex</span><span class="hl-brackets">(</span><span class="hl-prepro">NULL</span><span class="hl-code">, </span><span class="hl-prepro">FALSE</span><span class="hl-code">, </span><span class="hl-prepro">NULL</span><span class="hl-brackets">)</span><span class="hl-code">;
 
    </span><span class="hl-comment">//初始化线程数据</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">THREAD_DATA</span><span class="hl-code"> </span><span class="hl-identifier">threadData1</span><span class="hl-code">, </span><span class="hl-identifier">threadData2</span><span class="hl-code">;
    </span><span class="hl-identifier">threadData1</span><span class="hl-code">.</span><span class="hl-identifier">nMaxNum</span><span class="hl-code"> = </span><span class="hl-number">5</span><span class="hl-code">;
    </span><span class="hl-identifier">strcpy</span><span class="hl-brackets">(</span><span class="hl-identifier">threadData1</span><span class="hl-code">.</span><span class="hl-identifier">strThreadName</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">线程1</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-identifier">threadData2</span><span class="hl-code">.</span><span class="hl-identifier">nMaxNum</span><span class="hl-code"> = </span><span class="hl-number">10</span><span class="hl-code">;
    </span><span class="hl-identifier">strcpy</span><span class="hl-brackets">(</span><span class="hl-identifier">threadData2</span><span class="hl-code">.</span><span class="hl-identifier">strThreadName</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">线程2</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
 
 
    </span><span class="hl-comment">//创建第一个子线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">HANDLE</span><span class="hl-code"> </span><span class="hl-identifier">hThread1</span><span class="hl-code"> = </span><span class="hl-identifier">CreateThread</span><span class="hl-brackets">(</span><span class="hl-prepro">NULL</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">ThreadProc</span><span class="hl-code">, &amp;</span><span class="hl-identifier">threadData1</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-prepro">NULL</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-comment">//创建第二个子线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">HANDLE</span><span class="hl-code"> </span><span class="hl-identifier">hThread2</span><span class="hl-code"> = </span><span class="hl-identifier">CreateThread</span><span class="hl-brackets">(</span><span class="hl-prepro">NULL</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">ThreadProc</span><span class="hl-code">, &amp;</span><span class="hl-identifier">threadData2</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-prepro">NULL</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-comment">//关闭线程</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-identifier">CloseHandle</span><span class="hl-brackets">(</span><span class="hl-identifier">hThread1</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-identifier">CloseHandle</span><span class="hl-brackets">(</span><span class="hl-identifier">hThread2</span><span class="hl-brackets">)</span><span class="hl-code">;
 
    </span><span class="hl-comment">//主线程的执行路径</span><span class="hl-comment"></span><span class="hl-code">
    </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">i</span><span class="hl-code"> = </span><span class="hl-number">0</span><span class="hl-code">; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt; </span><span class="hl-number">5</span><span class="hl-code">; ++ </span><span class="hl-identifier">i</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-comment">//请求获得一个互斥量锁</span><span class="hl-comment"></span><span class="hl-code">
        </span><span class="hl-identifier">WaitForSingleObject</span><span class="hl-brackets">(</span><span class="hl-identifier">g_hMutex</span><span class="hl-code">, </span><span class="hl-identifier">INFINITE</span><span class="hl-brackets">)</span><span class="hl-code">;
        </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">主线程 === </span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">i</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
        </span><span class="hl-identifier">Sleep</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
        </span><span class="hl-comment">//释放互斥量锁</span><span class="hl-comment"></span><span class="hl-code">
        </span><span class="hl-identifier">ReleaseMutex</span><span class="hl-brackets">(</span><span class="hl-identifier">g_hMutex</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
 
    </span><span class="hl-identifier">system</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">pause</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-code">;
</span><span class="hl-brackets">}</span></div>
</div>
</div>

<p>结果：</p>

<pre>主线程 === 0 
线程1 &mdash; 0 
线程2 &mdash; 0 
主线程 === 1 
线程1 &mdash; 1 
线程2 &mdash; 1 
主线程 === 2 
线程1 &mdash; 2 
线程2 &mdash; 2 
主线程 === 3 
线程1 &mdash; 3 
线程2 &mdash; 3 
主线程 === 4 
线程1 &mdash; 4 
请按任意键继续&hellip; 线程2 &mdash; 4 
线程2 &mdash; 5 
线程2 &mdash; 6 
线程2 &mdash; 7 
线程2 &mdash; 8 
线程2 &mdash; 9</pre>


<p>为进一步理解线程同步的重要性和互斥量的使用方法，我们再来看一个例子。</p>

<p>买火车票是大家春节回家最为关注的事情，我们就简单模拟一下火车票的售票系统(为使程序简单，我们就抽出最简单的模型进行模拟)：有500张从北京到赣州的火车票，在8个窗口同时出售，保证系统的稳定性和数据的原子性。</p>
<h3>【Demo4】：模拟火车售票系统</h3>

<div class="example">
<h2 class="example">SaleTickets.h</h2>
<div class="example_code">
<div class="hl-main"><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">stdafx.h</span><span class="hl-quotes">&quot;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">windows.h</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">iostream</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">strstream</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"> </span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">string</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-reserved">using</span><span class="hl-code"> </span><span class="hl-types">namespace</span><span class="hl-code"> </span><span class="hl-identifier">std</span><span class="hl-code">;
 
</span><span class="hl-prepro">#define</span><span class="hl-code"> </span><span class="hl-identifier">NAME_LINE</span><span class="hl-code">   </span><span class="hl-number">40</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-comment">//定义线程函数传入参数的结构体</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-types">typedef</span><span class="hl-code"> </span><span class="hl-types">struct</span><span class="hl-code"> </span><span class="hl-identifier">__TICKET</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">nCount</span><span class="hl-code">;
    </span><span class="hl-types">char</span><span class="hl-code"> </span><span class="hl-identifier">strTicketName</span><span class="hl-brackets">[</span><span class="hl-identifier">NAME_LINE</span><span class="hl-brackets">]</span><span class="hl-code">;
 
    </span><span class="hl-identifier">__TICKET</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code"> : </span><span class="hl-identifier">nCount</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">memset</span><span class="hl-brackets">(</span><span class="hl-identifier">strTicketName</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">NAME_LINE</span><span class="hl-code"> * </span><span class="hl-reserved">sizeof</span><span class="hl-brackets">(</span><span class="hl-types">char</span><span class="hl-brackets">)</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
</span><span class="hl-brackets">}</span><span class="hl-identifier">TICKET</span><span class="hl-code">;
 
</span><span class="hl-types">typedef</span><span class="hl-code"> </span><span class="hl-types">struct</span><span class="hl-code"> </span><span class="hl-identifier">__THD_DATA</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-identifier">TICKET</span><span class="hl-code">* </span><span class="hl-identifier">pTicket</span><span class="hl-code">;
    </span><span class="hl-types">char</span><span class="hl-code"> </span><span class="hl-identifier">strThreadName</span><span class="hl-brackets">[</span><span class="hl-identifier">NAME_LINE</span><span class="hl-brackets">]</span><span class="hl-code">;
 
    </span><span class="hl-identifier">__THD_DATA</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code"> : </span><span class="hl-identifier">pTicket</span><span class="hl-brackets">(</span><span class="hl-prepro">NULL</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-identifier">memset</span><span class="hl-brackets">(</span><span class="hl-identifier">strThreadName</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">NAME_LINE</span><span class="hl-code"> * </span><span class="hl-reserved">sizeof</span><span class="hl-brackets">(</span><span class="hl-types">char</span><span class="hl-brackets">)</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
</span><span class="hl-brackets">}</span><span class="hl-identifier">THD_DATA</span><span class="hl-code">;
 
 
 </span><span class="hl-comment">//基本类型数据转换成字符串</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-types">template</span><span class="hl-code">&lt;</span><span class="hl-types">class</span><span class="hl-code"> </span><span class="hl-identifier">T</span><span class="hl-code">&gt;
</span><span class="hl-identifier">string</span><span class="hl-code"> </span><span class="hl-identifier">convertToString</span><span class="hl-brackets">(</span><span class="hl-types">const</span><span class="hl-code"> </span><span class="hl-identifier">T</span><span class="hl-code"> </span><span class="hl-identifier">val</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
    </span><span class="hl-identifier">string</span><span class="hl-code"> </span><span class="hl-identifier">s</span><span class="hl-code">;
    </span><span class="hl-identifier">std</span><span class="hl-code">::</span><span class="hl-identifier">strstream</span><span class="hl-code"> </span><span class="hl-identifier">ss</span><span class="hl-code">;
    </span><span class="hl-identifier">ss</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">val</span><span class="hl-code">;
    </span><span class="hl-identifier">ss</span><span class="hl-code"> &gt;&gt; </span><span class="hl-identifier">s</span><span class="hl-code">;
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-identifier">s</span><span class="hl-code">;
</span><span class="hl-brackets">}</span><span class="hl-code">
 
</span><span class="hl-comment">//售票程序</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-identifier">DWORD</span><span class="hl-code"> </span><span class="hl-identifier">WINAPI</span><span class="hl-code"> </span><span class="hl-identifier">SaleTicket</span><span class="hl-brackets">(</span><span class="hl-identifier">LPVOID</span><span class="hl-code"> </span><span class="hl-identifier">lpParameter</span><span class="hl-brackets">)</span><span class="hl-code">;</span></div>
</div>
</div>



<div class="example">
<h2 class="example">SaleTickets.cpp</h2>
<div class="example_code">
<div class="hl-main"><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">stdafx.h</span><span class="hl-quotes">&quot;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">windows.h</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&lt;</span><span class="hl-string">iostream</span><span class="hl-quotes">&gt;</span><span class="hl-prepro"></span><span class="hl-code">
</span><span class="hl-prepro">#include</span><span class="hl-prepro"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">SaleTickets.h</span><span class="hl-quotes">&quot;</span><span class="hl-prepro"></span><span class="hl-code">
 
</span><span class="hl-reserved">using</span><span class="hl-code"> </span><span class="hl-types">namespace</span><span class="hl-code"> </span><span class="hl-identifier">std</span><span class="hl-code">;
 
</span><span class="hl-types">extern</span><span class="hl-code"> </span><span class="hl-identifier">HANDLE</span><span class="hl-code"> </span><span class="hl-identifier">g_hMutex</span><span class="hl-code">;
 
</span><span class="hl-comment">//售票程序</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-identifier">DWORD</span><span class="hl-code"> </span><span class="hl-identifier">WINAPI</span><span class="hl-code"> </span><span class="hl-identifier">SaleTicket</span><span class="hl-brackets">(</span><span class="hl-identifier">LPVOID</span><span class="hl-code"> </span><span class="hl-identifier">lpParameter</span><span class="hl-brackets">)</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
 
    </span><span class="hl-identifier">THD_DATA</span><span class="hl-code">* </span><span class="hl-identifier">pThreadData</span><span class="hl-code"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">THD_DATA</span><span class="hl-code">*</span><span class="hl-brackets">)</span><span class="hl-identifier">lpParameter</span><span class="hl-code">;
    </span><span class="hl-identifier">TICKET</span><span class="hl-code">* </span><span class="hl-identifier">pSaleData</span><span class="hl-code"> = </span><span class="hl-identifier">pThreadData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">pTicket</span><span class="hl-code">;
    </span><span class="hl-reserved">while</span><span class="hl-brackets">(</span><span class="hl-identifier">pSaleData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">nCount</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">
    </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-comment">//请求获得一个互斥量锁</span><span class="hl-comment"></span><span class="hl-code">
        </span><span class="hl-identifier">WaitForSingleObject</span><span class="hl-brackets">(</span><span class="hl-identifier">g_hMutex</span><span class="hl-code">, </span><span class="hl-identifier">INFINITE</span><span class="hl-brackets">)</span><span class="hl-code">;
        </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-identifier">pSaleData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">nCount</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">
        </span><span class="hl-brackets">{</span><span class="hl-code">
            </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">pThreadData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">strThreadName</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">出售第</span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">pSaleData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">nCount</span><span class="hl-code"> -- &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">的票,</span><span class="hl-quotes">&quot;</span><span class="hl-code">;
            </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-identifier">pSaleData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">nCount</span><span class="hl-code"> &gt;= </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
                </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">出票成功!剩余</span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">pSaleData</span><span class="hl-code">-&gt;</span><span class="hl-identifier">nCount</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">张票.</span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
            </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
                </span><span class="hl-identifier">cout</span><span class="hl-code"> &lt;&lt; </span><span class="hl-quotes">&quot;</span><span class="hl-string">出票失败！该票已售完。</span><span class="hl-quotes">&quot;</span><span class="hl-code"> &lt;&lt; </span><span class="hl-identifier">endl</span><span class="hl-code">;
            </span><span class="hl-brackets">}</span><span class="hl-code">
        </span><span class="hl-brackets">}</span><span class="hl-code">
        </span><span class="hl-identifier">Sleep</span><span class="hl-brackets">(</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
        </span><span class="hl-comment">//释放互斥量锁</span><span class="hl-comment"></span><span class="hl-code">
        </span><span class="hl-identifier">ReleaseMutex</span><span class="hl-brackets">(</span><span class="hl-identifier">g_hMutex</span><span class="hl-brackets">)</span><span class="hl-code">;
    </span><span class="hl-brackets">}</span><span class="hl-code">
 
    </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-identifier">L</span><span class="hl-code">;
</span><span class="hl-brackets">}</span></div>
</div>
</div>

<p>测试程序：</p>

<pre>
//售票系统
void Test2()
{
    //创建一个互斥量
    g_hMutex = CreateMutex(NULL, FALSE, NULL);

    //初始化火车票
    TICKET ticket;
    ticket.nCount = 100;
    strcpy(ticket.strTicketName, "北京--&gt;赣州");

    const int THREAD_NUMM = 8;
    THD_DATA threadSale[THREAD_NUMM];
    HANDLE hThread[THREAD_NUMM];
    for(int i = 0; i &lt; THREAD_NUMM; ++ i)
    {
        threadSale[i].pTicket = &amp;ticket;
        string strThreadName = convertToString(i);

        strThreadName = "窗口" + strThreadName;

        strcpy(threadSale[i].strThreadName, strThreadName.c_str());

        //创建线程
        hThread[i] = CreateThread(NULL, NULL, SaleTicket, &amp;threadSale[i], 0, NULL);

        //请求获得一个互斥量锁
        WaitForSingleObject(g_hMutex, INFINITE);
        cout &lt;&lt; threadSale[i].strThreadName &lt;&lt; "开始出售 " &lt;&lt; threadSale[i].pTicket-&gt;strTicketName &lt;&lt; " 的票..." &lt;&lt; endl;
        //释放互斥量锁
        ReleaseMutex(g_hMutex);

        //关闭线程
        CloseHandle(hThread[i]);
    }

    system("pause");
}
</pre>

<p>结果：</p>


<pre>窗口0开始出售 北京&ndash;&gt;赣州 的票&hellip; 
窗口0出售第100的票,出票成功!剩余99张票. 
窗口1开始出售 北京&ndash;&gt;赣州 的票&hellip; 
窗口1出售第99的票,出票成功!剩余98张票. 
窗口0出售第98的票,出票成功!剩余97张票. 
窗口2开始出售 北京&ndash;&gt;赣州 的票&hellip; 
窗口2出售第97的票,出票成功!剩余96张票. 
窗口1出售第96的票,出票成功!剩余95张票. 
窗口0出售第95的票,出票成功!剩余94张票. 
窗口3开始出售 北京&ndash;&gt;赣州 的票&hellip; 
窗口3出售第94的票,出票成功!剩余93张票. 
窗口2出售第93的票,出票成功!剩余92张票. 
窗口1出售第92的票,出票成功!剩余91张票. 
窗口0出售第91的票,出票成功!剩余90张票. 
窗口4开始出售 北京&ndash;&gt;赣州 的票&hellip; 
窗口4出售第90的票,出票成功!剩余89张票. 
窗口3出售第89的票,出票成功!剩余88张票. 
窗口2出售第88的票,出票成功!剩余87张票. 
窗口1出售第87的票,出票成功!剩余86张票. 
窗口0出售第86的票,出票成功!剩余85张票. 
窗口5开始出售 北京&ndash;&gt;赣州 的票&hellip; 
窗口5出售第85的票,出票成功!剩余84张票. 
窗口4出售第84的票,出票成功!剩余83张票. 
窗口3出售第83的票,出票成功!剩余82张票. 
窗口2出售第82的票,出票成功!剩余81张票.</pre>




<blockquote><p>来源：http://blog.csdn.net/luoweifu/article/details/46835437</p></blockquote>
















				</div>
			</div>
			<div class="previous-next-links">
			<div class="previous-design-link">← <a href="../w3cnote/cpp-std-thread.html" rel="prev"> C++ std::thread</a> </div>
			<div class="next-design-link"><a href="../w3cnote/css-percentage-calculation.html" rel="next"> css 中的百分比计算方法</a> →</div>
			</div>
						<div class="article-heading-ad" id="w3cnote-ad728">
			<script async src=""></script>
			<!-- 移动版 自动调整 -->
			<ins class="adsbygoogle"
			     style="display:inline-block;min-width:300px;max-width:970px;width:100%;height:90px"
			     data-ad-client="ca-pub-5751451760833794"
			     data-ad-slot="1691338467"
			     data-ad-format="horizontal"></ins>
			<script>
			(adsbygoogle = window.adsbygoogle || []).push({});
			</script>
			</div>
			<style>
@media screen and (max-width: 768px) {
	#w3cnote-ad728 {
		display: none;
	}
}
p.note-author {
    border-bottom: 1px solid #ddd;
    font-size: 18px;
    font-weight: bold;
    color: #78a15a;
    padding-bottom: 2px;
    margin-bottom: 4px;
}
</style>
<script>
var aid = 19270;
</script>
	</div>
		
	</div>
	<div class="listcol last right-column">




<!--
	<div class="tab tab-light-blue"> 订阅</div>
	<div class="sidebar-box">
		<div class="socialicons">
			<a href="../feed" class="rss">RSS 订阅</a>
		
			<form action="//list.qq.com/cgi-bin/qf_compose_send" method="post">
			<input type="hidden" value="qf_booked_feedback" name="t">
			<input type="hidden" value="4b67b6b6c1f5e792559940cab4aebb8f1126fba880bff1a8" name="id">
			<input class="placeholder" id="feed_email" name="to" value="输入邮箱 订阅笔记" autocomplete="off">
			<input type="submit" value="订阅" class="btn btn-primary">
			</form>
		
		</div>
 
	</div>
-->	



<!--
	<div class="sidebar-box cate-list">
	<div class="sidebar-box recommend-here list-link">
			<a href="javascript:void(0);" style="font-size: 16px; color:#64854c;font-weight:bold;">笔记列表</a>
		</div>

 

</div>
-->

	 <div class="sidebar-box cate-list">
		 		

	 	<div class="sidebar-box recommend-here list-link">
			<a href="javascript:void(0);" style="font-size: 16px; color:#64854c;font-weight:bold;">教程列表</a>
		</div>
		
		<div class="cate-items"> 
				<a href="../ado">ADO 教程</a>
	<a href="../ajax">Ajax 教程</a>
	<a href="../android">Android 教程</a>
	<a href="../angularjs2">Angular2 教程</a>
	<a href="../angularjs">AngularJS 教程</a>
	<a href="../appml">AppML 教程</a>
	<a href="../asp">ASP 教程</a>
	<a href="../aspnet">ASP.NET 教程</a>
	<a href="../bootstrap">Bootstrap 教程</a>
	<a href="../bootstrap4">Bootstrap4 教程</a>
	<a href="../bootstrap5">Bootstrap5 教程</a>
	<a href="../cprogramming">C 教程</a>
	<a href="../csharp">C# 教程</a>
	<a href="../cplusplus">C++ 教程</a>
	<a href="../chartjs">Chart.js 教程</a>
	<a href="../cssref">CSS 参考手册</a>
	<a href="../css">CSS 教程</a>
	<a href="../css3">CSS3 教程</a>
	<a href="../django">Django 教程</a>
	<a href="../docker">Docker 教程</a>
	<a href="../dtd">DTD 教程</a>
	<a href="../echarts">ECharts 教程</a>
	<a href="../eclipse">Eclipse 教程</a>
	<a href="../firebug">Firebug 教程</a>
	<a href="../font-awesome">Font Awesome 图标</a>
	<a href="../foundation">Foundation 教程</a>
	<a href="../git">Git 教程</a>
	<a href="../go">Go 语言教程</a>
	<a href="../googleapi">Google 地图 API 教程</a>
	<a href="../highcharts">Highcharts 教程</a>
	<a href="../htmldom">HTML DOM 教程</a>
	<a href="../tags">HTML 参考手册</a>
	<a href="../charsets">HTML 字符集</a>
	<a href="../html">HTML 教程</a>
	<a href="../http">HTTP 教程</a>
	<a href="../ionic">ionic 教程</a>
	<a href="../ios">iOS 教程</a>
	<a href="../java">Java 教程</a>
	<a href="../jsref">JavaScript 参考手册</a>
	<a href="../js">Javascript 教程</a>
	<a href="../jeasyui">jQuery EasyUI 教程</a>
	<a href="../jquerymobile">jQuery Mobile 教程</a>
	<a href="../jqueryui">jQuery UI 教程</a>
	<a href="../jquery">jQuery 教程</a>
	<a href="../json">JSON 教程</a>
	<a href="../jsp">JSP 教程</a>
	<a href="../julia">Julia 教程</a>
	<a href="../kotlin">Kotlin 教程</a>
	<a href="../linux">Linux 教程</a>
	<a href="../lua">Lua 教程</a>
	<a href="../markdown">Markdown 教程</a>
	<a href="../matplotlib">Matplotlib 教程</a>
	<a href="../maven">Maven 教程</a>
	<a href="../memcached">Memcached 教程</a>
	<a href="../mongodb">MongoDB 教程</a>
	<a href="../mysql">MySQL 教程</a>
	<a href="../nodejs">Node.js 教程</a>
	<a href="../numpy">NumPy 教程</a>
	<a href="../pandas">Pandas 教程</a>
	<a href="../perl">Perl 教程</a>
	<a href="../php">PHP 教程</a>
	<a href="../postgresql">PostgreSQL 教程</a>
	<a href="../python3">Python 3 教程</a>
	<a href="../python">Python 基础教程</a>
	<a href="../r">R 教程</a>
	<a href="../rdf">RDF 教程</a>
	<a href="../react">React 教程</a>
	<a href="../redis">Redis 教程</a>
	<a href="../rss">RSS 教程</a>
	<a href="../ruby">Ruby 教程</a>
	<a href="../rust">Rust 教程</a>
	<a href="../sass">Sass 教程</a>
	<a href="../scala">Scala 教程</a>
	<a href="../scipy">SciPy 教程</a>
	<a href="../servlet">Servlet 教程</a>
	<a href="../soap">SOAP 教程</a>
	<a href="../sql">SQL 教程</a>
	<a href="../sqlite">SQLite 教程</a>
	<a href="../svg">SVG 教程</a>
	<a href="../svn">SVN 教程</a>
	<a href="../swift">Swift 教程</a>
	<a href="../tcpip">TCP/IP 教程</a>
	<a href="../typescript">TypeScript 教程</a>
	<a href="../vbscript">VBScript 教程</a>
	<a href="../vue2">Vue.js 教程</a>
	<a href="../vue3">Vue3 教程</a>
	<a href="../w3c">W3C 教程</a>
	<a href="../webservices">Web Service 教程</a>
	<a href="../wsdl">WSDL 教程</a>
	<a href="../xlink">XLink 教程</a>
	<a href="../dom">XML DOM 教程</a>
	<a href="../schema">XML Schema 教程</a>
	<a href="../xml">XML 教程</a>
	<a href="../xpath">XPath 教程</a>
	<a href="../xquery">XQuery 教程</a>
	<a href="../xslfo">XSLFO 教程</a>
	<a href="../xsl">XSLT 教程</a>
	<a href="../data-structures">数据结构</a>
	<a href="../regexp">正则表达式</a>
	<a href="../quiz">测验</a>
	<a href="../browsers">浏览器</a>
	<a href="../quality">网站品质</a>
	<a href="../web">网站建设指南</a>
	<a href="../hosting">网站服务器教程</a>
	<a href="../design-pattern">设计模式</a>
			
		</div> 
		 	 </div>
</div>
	</div>
</div>


<!-- 底部 -->
<div id="footer" class="mar-t50">
   <div class="runoob-block">
    <div class="runoob cf">
     <dl>
      <dt>
       在线实例
      </dt>
      <dd>
       &middot;<a target="_blank" href="../html/html-examples.html">HTML 实例</a>
      </dd>
      <dd>
       &middot;<a target="_blank" href="../css/css-examples.html">CSS 实例</a>
      </dd>
      <dd>
       &middot;<a target="_blank" href="../js/js-examples.html">JavaScript 实例</a>
      </dd>
      <dd>
       &middot;<a target="_blank" href="../ajx/ajax-examples.html">Ajax 实例</a>
      </dd>
       <dd>
       &middot;<a target="_blank" href="../jquery/jquery-examples.html">jQuery 实例</a>
      </dd>
      <dd>
       &middot;<a target="_blank" href="../xml/xml-examples.html">XML 实例</a>
      </dd>
      <dd>
       &middot;<a target="_blank" href="../java/java-examples.html">Java 实例</a>
      </dd>
     
     </dl>
     <dl>
      <dt>
      字符集&工具
      </dt>
      <dd>
       &middot; <a target="_blank" href="../charsets/html-charsets.html">HTML 字符集设置</a>
      </dd>
      <dd>
       &middot; <a target="_blank" href="../tags/html-ascii.html">HTML ASCII 字符集</a>
      </dd>
     <dd>
       &middot; <a target="_blank" href="https://c.runoob.com/front-end/6939/">JS 混淆/加密</a>
      </dd> 
      <dd>
       &middot; <a target="_blank" href="https://c.runoob.com/front-end/6232/">PNG/JPEG 图片压缩</a>
      </dd>
      <dd>
       &middot; <a target="_blank" href="../tags/html-colorpicker.html">HTML 拾色器</a>
      </dd>
      <dd>
       &middot; <a target="_blank" href="..//c.runoob.com/front-end/53">JSON 格式化工具</a>
      </dd>
      <dd>
       &middot; <a target="_blank" href="..//c.runoob.com/front-end/6680/">随机数生成器</a>
      </dd>
     </dl>
     <dl>
      <dt>
       最新更新
      </dt>
                   <dd>
       &middot;
      <a href="../matplotlib/matplotlib-imread.html" title="Matplotlib imread() 方法">Matplotlib imre...</a>
      </dd>
              <dd>
       &middot;
      <a href="../matplotlib/matplotlib-imsave.html" title="Matplotlib imsave() 方法">Matplotlib imsa...</a>
      </dd>
              <dd>
       &middot;
      <a href="../matplotlib/matplotlib-imshow.html" title="Matplotlib imshow() 方法">Matplotlib imsh...</a>
      </dd>
              <dd>
       &middot;
      <a href="../matplotlib/matplotlib-hist.html" title="Matplotlib 直方图">Matplotlib 直方图</a>
      </dd>
              <dd>
       &middot;
      <a href="../python3/python-func-object.html" title="Python object() 函数">Python object()...</a>
      </dd>
              <dd>
       &middot;
      <a href="../python3/python-ai-draw.html" title="Python AI 绘画">Python AI 绘画</a>
      </dd>
              <dd>
       &middot;
      <a href="../w3cnote/cursor-editor.html" title="神辅助 Cursor 编辑器，加入 GPT-4 让编码更轻松！">神辅助 Cursor ...</a>
      </dd>
             </dl>
     <dl>
      <dt>
       站点信息
      </dt>
      <dd>
       &middot;
       <a target="_blank" href="mailto:admin@runoob.com" rel="external nofollow">意见反馈</a>
       </dd>
      <dd>
       &middot;
      <a target="_blank" href="../disclaimer">免责声明</a>
       </dd>
      <dd>
       &middot;
       <a target="_blank" href="../aboutus">关于我们</a>
       </dd>
      <dd>
       &middot;
      <a target="_blank" href="../archives">文章归档</a>
      </dd>
    
     </dl>
    
     <div class="search-share">
      <div class="app-download">
        <div>
         <strong>关注微信</strong>
        </div>
      </div>
      <div class="share">
      <img width="128" height="128" src="/wp-content/themes/runoob/assets/images/qrcode.png" />
       </div>
     </div>
     
    </div>
   </div>
   <div class="w-1000 copyright">
     Copyright &copy; 2013-2023    <strong><a href="../" target="_blank">菜鸟教程</a></strong>&nbsp;
    <strong><a href="../" target="_blank">runoob.com</a></strong> All Rights Reserved. 备案号：<a target="_blank" rel="nofollow" href="https://beian.miit.gov.cn/">闽ICP备15012807号-1</a>
   </div>
  </div>
  <div class="fixed-btn">
    <a class="go-top" href="javascript:void(0)" title="返回顶部"> <i class="fa fa-angle-up"></i></a>
    <a class="qrcode"  href="javascript:void(0)" title="关注我们"><i class="fa fa-qrcode"></i></a>
    <a class="writer" style="display:none" href="javascript:void(0)"   title="标记/收藏"><i class="fa fa-star" aria-hidden="true"></i></a>
    <!-- qrcode modal -->
    <div id="bottom-qrcode" class="modal panel-modal hide fade in">
      <h4>微信关注</h4>
      <div class="panel-body"><img alt="微信关注" width="128" height="128" src="/wp-content/themes/runoob/assets/images/qrcode.png"></div> 
    </div>
  </div>

 <div style="display:none;">
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-84264393-2"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-84264393-2');
</script>
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?3eec0b7da6548cf07db3bc477ea905ee";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

</div>
<script>
window.jsui={
    www: 'https://www.runoob.com',
    uri: 'https://www.runoob.com/wp-content/themes/runoob'
};
</script>

<script src=""></script>
<script src=""></script>

</body>
</html>